package oicon;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

class AutoScrolling extends JPanel {
	public AutoScrolling() {
		super(new BorderLayout());
		JLabel label = new JLabel();
		// "CRW_3857_JFR.jpg" > http://sozai-free.com/
		label.setIcon(new ImageIcon("icon/commit.gif"));
		label.setText("asdfsafdasdfsadfdsfdsf");
		JScrollPane scroll = new JScrollPane(/*
				JScrollPane.VERTICAL_SCROLLBAR_NEVER,
				JScrollPane.HORIZONTAL_SCROLLBAR_NEVER*/);
		JViewport v = scroll.getViewport();
		v.add(label);
		new DragMoverListener(v, label);
		add(scroll);
		scroll.setPreferredSize(new Dimension(320, 320));
	}

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				createAndShowGUI();
			}
		});
	}

	public static void createAndShowGUI() {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		final JFrame frame = new JFrame("@title@");
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		frame.getContentPane().add(new AutoScrolling());
		frame.pack();
		frame.setResizable(true);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}
}

class DragMoverListener extends MouseInputAdapter implements ActionListener,
									HierarchyListener {
	private static final int SPEED = 2;
	private final Cursor dc;
	private final Cursor hc = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
	private final Rectangle rect = new Rectangle();
	private final javax.swing.Timer scroller;
	private final JComponent label;
	private final JViewport vport;
	private Point startPt = new Point();
	private Point move = new Point();

	public DragMoverListener(JViewport vport, JComponent comp) {
		this.vport = vport;
		this.label = comp;
		this.dc = label.getCursor();
		this.scroller = new javax.swing.Timer(5, this);
		vport.addMouseMotionListener(this);
		vport.addMouseListener(this);
		vport.addHierarchyListener(this);
	}

	public void hierarchyChanged(HierarchyEvent e) {
		if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0
				&& !vport.isDisplayable()) {
			scroller.stop();
		}
	}

	public void actionPerformed(ActionEvent e) {
		Rectangle vr = vport.getViewRect();
		int w = vr.width;
		int h = vr.height;
		Point ptZero = SwingUtilities.convertPoint(vport, 0, 0, label);
		rect.setRect(ptZero.x - move.x, ptZero.y - move.y, w, h);
		label.scrollRectToVisible(rect);
	}

	public void mouseDragged(MouseEvent e) {
		scroller.stop();
		Point pt = e.getPoint();
		move.setLocation(SPEED * (pt.x - startPt.x), SPEED * (pt.y - startPt.y));
		startPt.setLocation(pt);
		scroller.start();
	}

	public void mousePressed(MouseEvent e) {
		// label.setCursor(hc);
		startPt.setLocation(e.getPoint());
		scroller.stop();
	}

	public void mouseReleased(MouseEvent e) {
		// label.setCursor(dc);
	}

	public void mouseExited(MouseEvent e) {
		// label.setCursor(dc);
		move.setLocation(0, 0);
		scroller.stop();
	}
}